package com.gopay.bis.service.bank.impl.micro;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.manager.bank.micro.SpdbMicroPayManager;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.MicroPayConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.spdb.agpay.MicroPayBody;
import com.gopay.common.domain.bank.spdb.agpay.QueryOrderBody;
import com.gopay.common.domain.bank.spdb.agpay.RefundBody;
import com.gopay.common.domain.bank.spdb.agpay.ReverseBody;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.TransUtil;
import com.gopay.remote.bank.MicroPayInteractRemoteService;

public class SpdbMicroPayServiceImpl implements MicroPayInteractRemoteService {

	private static Logger logger = LoggerFactory.getLogger(SpdbMicroPayServiceImpl.class);
	@Resource(name = "mpPaySpdbManager")
	private SpdbMicroPayManager mpPaySpdbManager;

	@Override
	public Result pay(BaseMessage base) throws GopayException {
		logger.info("------------SpdbMicroPayServiceImpl pay start-------------");
		long beginTime = System.currentTimeMillis();
		Result result = new Result(false);
		try {
			MicroPayBody message = new MicroPayBody();
			BeanUtils.copyProperties(base, message);
			MicroPayBody res = (MicroPayBody) mpPaySpdbManager.payment(message);
			result.setDefaultModel(res.isSuccess());
			result.setModel("res", res);
			Map<String, String> param = new HashMap<String, String>();
			if (res.isSuccess() && MicroPayConstants.SPDB_MICRO_PAY_RESULT_SUCCESS.equals(res.getRespcd())) {
				// 支付成功
				param.put("orderId", base.getOrderId());
				// 转化金额以元为单位
				param.put("amt", TransUtil.amountConvert2Yuan(String.valueOf(new BigDecimal(res.getTxamt()))));
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "00");
				param.put("retCode", "00");
				param.put("retMsg", "验签成功");
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setOrderStatus(true);
			} else if (res.isSuccess() && MicroPayConstants.SPDB_MICRO_PAY_RESULT_USERPAYING.equals(res.getRespcd())) {
				// 需要用户输入支付密码
				param.put("orderId", base.getOrderId());
				param.put("amt", TransUtil.amountConvert2Yuan(String.valueOf(new BigDecimal(res.getTxamt()))));
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "02");
				param.put("retCode", "01");
				String errorMessage = StringUtils.isEmpty(res.getErrorDetail()) ? res.getErrMessage()
						: res.getErrorDetail();
				param.put("retMsg", errorMessage);
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setErrorMsg(errorMessage);
				result.setOrderStatus(false);
			} else {
				param.put("orderId", base.getOrderId());
				param.put("amt", TransUtil.amountConvert2Yuan(String.valueOf(new BigDecimal(res.getTxamt()))));
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "01");
				param.put("retCode", "01");
				String errorMessage = StringUtils.isEmpty(res.getErrorDetail()) ? res.getErrMessage()
						: res.getErrorDetail();
				param.put("retMsg", errorMessage);
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setErrorMsg(errorMessage);
				result.setOrderStatus(false);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7025);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ SpdbMicroPayServiceImpl pay end，耗时(ms):" + (endTime - beginTime));
		return result;

	}

	@Override
	public Result orderQuery(BaseMessage base) throws GopayException {
		logger.info("------------SpdbMicroPayServiceImpl orderQuery start-------------");
		long beginTime = System.currentTimeMillis();
		Result result = new Result(false);
		try {
			QueryOrderBody message = new QueryOrderBody();
			BeanUtils.copyProperties(base, message);
			QueryOrderBody res = (QueryOrderBody) mpPaySpdbManager.orderQuery(message);
			res.setAmount(new BigDecimal(TransUtil.amountConvert2Yuan(String.valueOf(new BigDecimal(res.getTxamt())))));
			result.setDefaultModel(res);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ SpdbMicroPayServiceImpl orderQuery end，耗时(ms):" + (endTime - beginTime));
		return result;

	}

	@Override
	public Result refund(BaseMessage base) throws GopayException {
		logger.info("------------SpdbMicroPayServiceImpl refund start-------------");
		long beginTime = System.currentTimeMillis();
		Result result = new Result(false);
		try {
			RefundBody message = new RefundBody();
			BeanUtils.copyProperties(base, message);
			RefundBody res = (RefundBody) mpPaySpdbManager.refund(message);
			result.setDefaultModel(res);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ SpdbMicroPayServiceImpl refund end，耗时(ms):" + (endTime - beginTime));
		return result;

	}

	@Override
	public Result refundQuery(BaseMessage base) throws GopayException {
		logger.info("------------SpdbMicroPayServiceImpl refundQuery start-------------");
		long beginTime = System.currentTimeMillis();
		Result result = new Result(false);
		try {
			QueryOrderBody message = new QueryOrderBody();
			BeanUtils.copyProperties(base, message);
			QueryOrderBody res = (QueryOrderBody) mpPaySpdbManager.orderQuery(message);
			res.setAmount(new BigDecimal(TransUtil.amountConvert2Yuan(String.valueOf(new BigDecimal(res.getTxamt())))));
			result.setDefaultModel(res);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ SpdbMicroPayServiceImpl refundQuery end，耗时(ms):" + (endTime - beginTime));
		return result;
	}

	@Override
	public Result reverse(BaseMessage base) throws GopayException {
		logger.info("------------SpdbMicroPayServiceImpl reverse start-------------");
		long beginTime = System.currentTimeMillis();
		Result result = new Result(false);
		try {
			ReverseBody message = new ReverseBody();
			BeanUtils.copyProperties(base, message);
			Map<String, String> param = new HashMap<String, String>();
			ReverseBody res = (ReverseBody) mpPaySpdbManager.reverse(message);
			
			logger.info("------返回对象为：" +ToStringBuilder.reflectionToString(res));
			result.setDefaultModel(res.isSuccess());
			if (res.isSuccess() && MicroPayConstants.SPDB_MICRO_PAY_RESULT_SUCCESS.equals(res.getRespcd())) {
				param.put("orderId", message.getOrderId());
				param.put("amt", base.getAmount().toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "00");
				param.put("retCode", "00");
				param.put("retMsg", "验签成功");
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setOrderStatus(true);
			} else {
				param.put("orderId", message.getOrderId());
				param.put("amt", base.getAmount().toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "01");
				param.put("retCode", "01");
				// 记录数据库失败信息 add by zhengxue 20170313
				String errorMessage =StringUtils.isEmpty(res.getErrorDetail()) ? res.getErrMessage()
						: res.getErrorDetail();
				param.put("retMsg", errorMessage);
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setOrderStatus(false);
			}
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			// 需新增错误码
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E1181);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ SpdbMicroPayServiceImpl reverse end，耗时(ms):" + (endTime - beginTime));
		return result;

	}

	@Override
	public Result reverseQuery(BaseMessage base) throws GopayException {
		logger.info("------------SpdbMicroPayServiceImpl reverseQuery start-------------");
		long beginTime = System.currentTimeMillis();
		Result result = new Result(false);
		try {
			QueryOrderBody message = new QueryOrderBody();
			BeanUtils.copyProperties(base, message);
			QueryOrderBody res = (QueryOrderBody) mpPaySpdbManager.orderQuery(message);
			res.setAmount(new BigDecimal(TransUtil.amountConvert2Yuan(String.valueOf(new BigDecimal(res.getTxamt())))));
			result.setDefaultModel(res);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ SpdbMicroPayServiceImpl reverseQuery end，耗时(ms):" + (endTime - beginTime));
		return result;

	}
}
